﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;
 
namespace PACKETPARSERMAX20.CodeGen
{
    class TableCodeGenerator : Data.DataAccessBase
    {
        public TableCodeGenerator(string connstr)
            : base(connstr)
        {
        }

        public static void GenerateCode(bool all)
        {
            string dest = ".\\MangosTables\\";

            if (!System.IO.Directory.Exists(dest)) System.IO.Directory.CreateDirectory(dest);

            string template = System.IO.File.ReadAllText(@".\TableCodeTemplate.txt");

            if (all)
            {
                var t = new TableCodeGenerator(GetConnectionString("mangos"));

                var tables = t.GetTables();

                foreach (string table in tables)
                {
                    GenerateCodeForTable(table, template, dest);
                }
            }
            else
            {
                GenerateCodeForTable("creature_template", template, dest);
                GenerateCodeForTable("creature_equip_template", template, dest);
                GenerateCodeForTable("creature_template_addon", template, dest);
                GenerateCodeForTable("quest_template", template, dest);
                GenerateCodeForTable("item_template", template, dest);
                GenerateCodeForTable("gameobject_template", template, dest);
                GenerateCodeForTable("npc_text", template, dest);
                GenerateCodeForTable("npc_trainer", template, dest);
                GenerateCodeForTable("npc_vendor", template, dest);
                GenerateCodeForTable("npc_spellclick_spells", template, dest);
                GenerateCodeForTable("creature", template, dest);
                GenerateCodeForTable("creature_addon", template, dest);
                GenerateCodeForTable("creature_model_info", template, dest);
                GenerateCodeForTable("creature_movement", template, dest);
                GenerateCodeForTable("creature_questrelation", template, dest);
                GenerateCodeForTable("creature_involvedrelation", template, dest);
                GenerateCodeForTable("gameobject", template, dest);
                GenerateCodeForTable("gossip_menu", template, dest);
                GenerateCodeForTable("gossip_menu_option", template, dest);
                GenerateCodeForTable("quest_poi", template, dest);
                GenerateCodeForTable("quest_poi_points", template, dest);
            }
        }

        public static void GenerateCodeForTable(string pTableName, string pTemplate, string pDest)
        {
            string template = pTemplate.Replace("[TABLE]", pTableName.ToLower());

            using (var sw = new System.IO.StreamWriter(pDest + pTableName + ".cs"))
            {
                using (var con = new MySqlConnection(GetConnectionString("mangos")))
                {
                    con.Open();
                    using (var command = con.CreateCommand())
                    {

                        command.CommandType = System.Data.CommandType.Text;
                        command.CommandText = string.Format("select * from {0} limit 1", pTableName);

                        try
                        {
                            var sb_object = new StringBuilder();
                            var sb_Insert_part1 = new StringBuilder();
                            var sb_Insert_part2 = new StringBuilder();
                            var sb_Insert_part3 = new StringBuilder();
                            var sb_Update = new StringBuilder();


                            sb_Insert_part1.Append(string.Format("INSERT IGNORE INTO `{0}` (", pTableName.ToLower()));
                            sb_Insert_part2.Append(" VALUES (");
                            sb_Insert_part3.Append("\", ");

                            sb_Update.AppendLine("\t\t\tsb.Append(\"UPDATE `" + pTableName.ToLower() + "` SET \");");

                            using (var dr = command.ExecuteReader())
                            {

                                for (int i = 0; i < dr.FieldCount; i++)
                                {
                                    string fieldname = dr.GetName(i).ToLower();
                                    string valuename = fieldname;

                                    if (valuename == "class") { valuename = "class_"; }

                                    if (i != 0)
                                    {
                                        sb_Update.AppendLine("\t\t\tif(" + valuename + " != null)");
                                        sb_Update.AppendLine("\t\t\t{");
                                        if (dr.GetFieldType(i) == typeof(System.String))
                                        {
                                            sb_Update.AppendLine("\t\t\t\tsb.AppendLine(\"`" + fieldname + "`='\" + " + valuename + ".MySQLDBString() + \"'\");");
                                        }
                                        else
                                        {
                                            sb_Update.AppendLine("\t\t\t\tsb.AppendLine(\"`" + fieldname + "`='\" + " + valuename + ".Value.ToString() + \"'\");");
                                        }
                                        sb_Update.AppendLine("\t\t\t}");
                                    }

                                    if (i == dr.FieldCount - 1)
                                    {
                                        sb_Insert_part1.Append(string.Format("`{0}`)", fieldname));
                                        sb_Insert_part2.Append("'{" + i.ToString() + "}');");
                                        if (dr.GetFieldType(i) == typeof(System.String))
                                        {
                                            sb_Insert_part3.Append(valuename + ".MySQLDBString());");
                                        }
                                        else
                                        {
                                            sb_Insert_part3.Append(valuename + ".GetValueOrDefault());");
                                        }
                                    }
                                    else
                                    {
                                        sb_Insert_part1.Append(string.Format("`{0}`, ", fieldname));
                                        sb_Insert_part2.Append("'{" + i.ToString() + "}', ");

                                        if (dr.GetFieldType(i) == typeof(System.String))
                                        {
                                            sb_Insert_part3.Append(valuename + ".MySQLDBString(), ");
                                        }
                                        else
                                        {
                                            sb_Insert_part3.Append(valuename + ".GetValueOrDefault(), ");
                                        }

                                    }

                                    if (dr.GetFieldType(i) == typeof(System.String))
                                    {
                                        sb_object.AppendLine(string.Format("\t\tpublic {0} {1};", dr.GetFieldType(i), valuename));
                                    }
                                    else
                                    {
                                        sb_object.AppendLine(string.Format("\t\tpublic {0}? {1};", dr.GetFieldType(i), valuename));
                                    }

                                }
                                sb_Update.AppendLine("\t\t\t\tsb = sb.Replace(\"\\r\\n\", \", \");");
                                sb_Update.AppendLine("\t\t\t\tsb.Append(\" WHERE `" + dr.GetName(0).ToLower() + "`='\" + " + dr.GetName(0).ToLower() + ".Value.ToString() + \"';\");");
                                sb_Update.AppendLine("\t\t\t\tsb = sb.Replace(\",  WHERE\", \" WHERE\");");
                            }

                            template = template.Replace("[FIELDS]", sb_object.ToString());
                            template = template.Replace("[INSERT]", sb_Insert_part1.ToString() + sb_Insert_part2.ToString() + sb_Insert_part3.ToString());
                            template = template.Replace("[UPDATE]", sb_Update.ToString());
                            sw.Write(template);



                        }
                        catch (Exception exc)
                        {
                            Console.WriteLine("Error: {0}, {1}", exc.Message, command.CommandText);
                        }
                    }

                }
                sw.Close();
            }
        }
    }
}
